package com.ywu.application.standard.demandManagement.service;

import com.ywu.application.standard.adminUser.entity.UserEntity;
import com.ywu.application.standard.adminUser.service.UserService;
import com.ywu.boot.context.YwuContext;
import com.ywu.boot.context.YwuContextHolder;
import com.ywu.common.entity.PageList;
import com.ywu.common.gson.GsonUtils;
import com.ywu.common.page.PageService;
import com.ywu.common.result.CommonResult;
import com.ywu.common.utils.TimerIdGenerateUtil;
import com.ywu.application.standard.demandManagement.data.YwuDemandManageProjectRepository;
import com.ywu.application.standard.demandManagement.data.YwuDemandManageRepository;
import com.ywu.application.standard.demandManagement.dto.YwuDemandManageProjectDto;
import com.ywu.application.standard.demandManagement.dto.YwuDemandManageProjectGroupDto;
import com.ywu.application.standard.demandManagement.dto.YwuDemandManageProjectVersionDto;
import com.ywu.application.standard.demandManagement.entity.YwuDemandManageProjectEntity;
import com.ywu.application.standard.demandManagement.entity.YwuDemandManageProjectGroupEntity;
import com.ywu.application.standard.demandManagement.entity.YwuDemandManageProjectVersionEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName YwuDemandManageProjectService
 * @Description TODO
 * @Author GroundDemo
 * @Date 2025/3/31 13:30
 * @Version 1.0
 **/
@Service
@Slf4j
public class YwuDemandManageProjectService {

    @Autowired
    private YwuDemandManageProjectRepository repository;

    @Autowired
    private YwuDemandManageRepository demandManageRepository;

    @Autowired
    private UserService userService;

    /**
    * @Author GroundDemo
    * @Description 分页查询项目信息
    * @Date 13:31 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryProjectList(YwuDemandManageProjectDto dto) {
        // 设置租户信息
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        dto.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        PageService.execPageStartAndEnd(dto.getPageInfo());
        // 查询数量
        int count = repository.queryListCount(dto);
        PageList<YwuDemandManageProjectEntity> pageListRes = new PageList<>();
        pageListRes.setPageIndex(dto.getPageInfo().getPageIndex());
        pageListRes.setPageSize(dto.getPageInfo().getPageSize());
        if (count == 0) {
            pageListRes.setDataList(new ArrayList<>());
        } else {
            // 查询kafka消息列表
            List<YwuDemandManageProjectEntity> entities = repository.queryList(dto);
            if (CollectionUtils.isEmpty(entities)) {
                pageListRes.setDataList(new ArrayList<>());
            } else {
                // 关联查询出用户账号
                List<Integer> userIds = entities.stream().map(YwuDemandManageProjectEntity::getProjectOwner).collect(Collectors.toList());
                CommonResult<List<UserEntity>> spiRes = userService.queryUserByUserIdBatch(userIds);
                if (Objects.isNull(spiRes) || !spiRes.getCode().equals("200")) {
                    log.error("query user info error {}", GsonUtils.serialize(spiRes));
                    return CommonResult.error().setMessage("query user info error");
                }
                List<UserEntity> data = spiRes.getData();
                Map<Integer, UserEntity> userMap = data.stream().collect(Collectors.toMap(UserEntity::getId, res -> res, (v1, v2) -> v1));
                entities.forEach(res -> {
                    if (userMap.containsKey(res.getProjectOwner())) {
                        UserEntity userEntity = userMap.get(res.getProjectOwner());
                        res.setProjectOwnerAccount(userEntity.getUserAccount());
                    }
                });
                pageListRes.setDataList(entities);
            }
        }
        pageListRes.setRecordCount(count);
        return CommonResult.success(pageListRes);
    }

    /**
    * @Author GroundDemo
    * @Description 校验项目名称是否存在
    * @Date 13:36 2025/3/31
    * @Param [dto]
    * @return boolean
    **/
    private boolean checkProjectNameExist(YwuDemandManageProjectDto dto) {
        YwuDemandManageProjectEntity search = new YwuDemandManageProjectEntity();
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        search.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        search.setProjectName(dto.getProjectName());
        YwuDemandManageProjectEntity queryEntity = repository.getEntity(search);
        return Objects.nonNull(queryEntity);
    }

    /**
    * @Author GroundDemo
    * @Description 校验ID是否存在
    * @Date 13:43 2025/3/31
    * @Param [dto]
    * @return boolean
    **/
    private boolean checkProjectIdExist(YwuDemandManageProjectDto dto) {
        YwuDemandManageProjectEntity search = new YwuDemandManageProjectEntity();
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        search.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        search.setId(dto.getId());
        YwuDemandManageProjectEntity queryEntity = repository.getEntity(search);
        return Objects.nonNull(queryEntity);
    }

    /**
    * @Author GroundDemo
    * @Description 创建项目
    * @Date 13:33 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> createProject(YwuDemandManageProjectDto dto) {
        // 校验项目名是否存在
        boolean checkRes = checkProjectNameExist(dto);
        if (checkRes) {
            log.error("project name has exist");
            return CommonResult.error().setMessage("project name has exist");
        }
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 构建对象
        YwuDemandManageProjectEntity create = new YwuDemandManageProjectEntity();
        BeanUtils.copyProperties(dto, create);
        create.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        create.setId(TimerIdGenerateUtil.nextId());
        create.createInfo(currentContext.getYwuContextUser().getUserAccount());
        repository.insertProject(create);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 修改项目
    * @Date 13:35 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> updateProject(YwuDemandManageProjectDto dto) {
        // 校验项目名是否存在
        boolean checkRes = checkProjectNameExist(dto);
        if (checkRes) {
            log.error("project name has exist");
            return CommonResult.error().setMessage("project name has exist");
        }
        // 校验ID是否存在
        checkRes = checkProjectIdExist(dto);
        if (!checkRes) {
            log.error("project id is not exist");
            return CommonResult.error().setMessage("project id is not exist");
        }
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        YwuDemandManageProjectEntity update = new YwuDemandManageProjectEntity();
        BeanUtils.copyProperties(dto, update);
        update.updateInfo(currentContext.getYwuContextUser().getUserAccount());
        repository.updateProject(update);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 删除项目
    * @Date 13:41 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    @Transactional
    public CommonResult<Object> deleteProject(YwuDemandManageProjectDto dto) {
        // 校验ID是否存在
        boolean checkRes = checkProjectIdExist(dto);
        if (!checkRes) {
            log.error("project id is not exist");
            return CommonResult.error().setMessage("project id is not exist");
        }
        // 删除数据
        YwuDemandManageProjectEntity delete = new YwuDemandManageProjectEntity();
        delete.setId(dto.getId());
        repository.deleteProject(delete);
        // 删除项目时同时删除版本信息和项目下的所有需求以及用户组信息
        repository.deleteProjectVersionByProjectId(delete);
        repository.deleteGroupUserByProjectId(delete);
        demandManageRepository.deleteDemandByProjectId(delete);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 查询项目组成员信息
    * @Date 14:00 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryProjectGroupList(YwuDemandManageProjectGroupDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 判断当前租户是否可以查询到当前项目
        YwuDemandManageProjectEntity search = new YwuDemandManageProjectEntity();
        search.setId(dto.getProjectId());
        search.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        YwuDemandManageProjectEntity queryEntity = repository.getEntity(search);
        if (Objects.isNull(queryEntity)) {
            log.error("project is not exist");
            return CommonResult.error().setMessage("project is not exist");
        }
        // 查询用户列表
        List<YwuDemandManageProjectGroupEntity> queryList = repository.queryGroupUserList(dto);
        if (CollectionUtils.isEmpty(queryList)) {
            return CommonResult.success(new ArrayList<>());
        }
        // 关联查询出用户账号
        List<Integer> userIds = queryList.stream().map(res -> Integer.parseInt(res.getUserId())).collect(Collectors.toList());
        CommonResult<List<UserEntity>> spiRes = userService.queryUserByUserIdBatch(userIds);
        if (Objects.isNull(spiRes) || !spiRes.getCode().equals("200")) {
            log.error("queryProjectGroupList query user info error {}", GsonUtils.serialize(spiRes));
            return CommonResult.error().setMessage("queryProjectGroupList query user info error");
        }
        List<UserEntity> data = spiRes.getData();
        Map<Integer, UserEntity> userMap = data.stream().collect(Collectors.toMap(UserEntity::getId, res -> res, (v1, v2) -> v1));
        queryList.forEach(res -> {
            if (userMap.containsKey(Integer.parseInt(res.getUserId()))) {
                UserEntity userEntity = userMap.get(Integer.parseInt(res.getUserId()));
                res.setUserAccount(userEntity.getUserAccount());
            }
        });
        return CommonResult.success(queryList);
    }

    /**
    * @Author GroundDemo
    * @Description 校验是否可以操作项目
    * @Date 15:07 2025/3/31
    * @Param [projectId]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    private CommonResult<Object> checkOperateProject(String projectId) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 根据项目ID查询项目信息
        YwuDemandManageProjectEntity search = new YwuDemandManageProjectEntity();
        search.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        search.setId(projectId);
        YwuDemandManageProjectEntity queryEntity = repository.getEntity(search);
        if (Objects.isNull(queryEntity)) {
            log.error("checkOperateProject project is not exist");
            return CommonResult.error().setMessage("checkOperateProject project is not exist");
        }
        // 判断当前的用户是否为项目的owner
        if (!Objects.equals(currentContext.getYwuContextUser().getId(), queryEntity.getProjectOwner())) {
            // 非owner无法操作用户的添加
            log.error("checkOperateProject project is not owner");
            return CommonResult.error().setMessage("checkOperateProject project is not owner");
        }
        return null;
    }

    /**
    * @Author GroundDemo
    * @Description 添加项目组用户
    * @Date 14:05 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> addGroupUser(YwuDemandManageProjectGroupDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 校验当前用户是否有权限添加用户组信息
        CommonResult<Object> result = checkOperateProject(dto.getProjectId());
        if (Objects.nonNull(result)) {
            return result;
        }
        // 添加数据
        YwuDemandManageProjectGroupEntity insert = new YwuDemandManageProjectGroupEntity();
        BeanUtils.copyProperties(dto, insert);
        insert.setId(TimerIdGenerateUtil.nextId());
        insert.createInfo(currentContext.getYwuContextUser().getUserAccount());
        repository.insertGroupUser(insert);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 删除项目组用户
    * @Date 14:27 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> deleteGroupUser(YwuDemandManageProjectGroupDto dto) {
        // 查询当前要删除的信息
        YwuDemandManageProjectGroupEntity searchGroupEntity = new YwuDemandManageProjectGroupEntity();
        searchGroupEntity.setId(dto.getId());
        YwuDemandManageProjectGroupEntity groupUserEntity = repository.getGroupUserEntity(searchGroupEntity);
        if (Objects.isNull(groupUserEntity)) {
            log.error("deleteGroupUser id is not exist");
            return CommonResult.error().setMessage("deleteGroupUser id is not exist");
        }
        // 校验当前用户是否有权限添加用户组信息
        CommonResult<Object> result = checkOperateProject(groupUserEntity.getProjectId());
        if (Objects.nonNull(result)) {
            return result;
        }
        // 删除数据
        YwuDemandManageProjectGroupEntity delete = new YwuDemandManageProjectGroupEntity();
        delete.setId(dto.getId());
        repository.deleteGroupUser(delete);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 查询项目版本列表
    * @Date 14:38 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryProjectVersionList(YwuDemandManageProjectVersionDto dto) {
        // 设置租户信息
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        dto.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        PageService.execPageStartAndEnd(dto.getPageInfo());
        // 查询数量
        int count = repository.queryVersionListCount(dto);
        PageList<YwuDemandManageProjectVersionEntity> pageListRes = new PageList<>();
        pageListRes.setPageIndex(dto.getPageInfo().getPageIndex());
        pageListRes.setPageSize(dto.getPageInfo().getPageSize());
        if (count == 0) {
            pageListRes.setDataList(new ArrayList<>());
        } else {
            // 查询kafka消息列表
            List<YwuDemandManageProjectVersionEntity> entities = repository.queryVersionList(dto);
            if (CollectionUtils.isEmpty(entities)) {
                pageListRes.setDataList(new ArrayList<>());
            } else {
                pageListRes.setDataList(entities);
            }
        }
        pageListRes.setRecordCount(count);
        return CommonResult.success(pageListRes);
    }

    /**
    * @Author GroundDemo
    * @Description 添加项目版本
    * @Date 14:57 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> createProjectVersion(YwuDemandManageProjectVersionDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        // 校验当前用户是否有权限添加用户组信息
        CommonResult<Object> result = checkOperateProject(dto.getProjectId());
        if (Objects.nonNull(result)) {
            return result;
        }
        // 插入数据
        YwuDemandManageProjectVersionEntity insert = new YwuDemandManageProjectVersionEntity();
        BeanUtils.copyProperties(dto, insert);
        insert.setId(TimerIdGenerateUtil.nextId());
        insert.createInfo(currentContext.getYwuContextUser().getUserAccount());
        repository.insertProjectVersion(insert);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 修改项目版本信息
    * @Date 15:11 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> updateProjectVersion(YwuDemandManageProjectVersionDto dto) {
        // 查询当前版本的信息
        YwuDemandManageProjectVersionEntity searchEntity = new YwuDemandManageProjectVersionEntity();
        searchEntity.setId(dto.getId());
        YwuDemandManageProjectVersionEntity versionEntity = repository.getProjectVersionEntity(searchEntity);
        if (Objects.isNull(versionEntity)) {
            log.error("updateProjectVersion id is not exist");
            return CommonResult.error().setMessage("updateProjectVersion id is not exist");
        }
        // 校验修改之前的项目是否有权限操作
        CommonResult<Object> result = checkOperateProject(versionEntity.getProjectId());
        if (Objects.nonNull(result)) {
            return result;
        }
        // 校验修改之后的项目是否有权限操作
        if (!dto.getProjectId().equals(versionEntity.getProjectId())) {
            result = checkOperateProject(dto.getProjectId());
            if (Objects.nonNull(result)) {
                return result;
            }
        }
        // 修改数据
        YwuDemandManageProjectVersionEntity update = new YwuDemandManageProjectVersionEntity();
        BeanUtils.copyProperties(dto, update);
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        update.updateInfo(currentContext.getYwuContextUser().getUserAccount());
        repository.updateProjectVersion(update);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 删除项目版本信息
    * @Date 15:21 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> deleteProjectVersion(YwuDemandManageProjectVersionDto dto) {
        // 根据ID查询版本信息
        YwuDemandManageProjectVersionEntity searchEntity = new YwuDemandManageProjectVersionEntity();
        searchEntity.setId(dto.getId());
        YwuDemandManageProjectVersionEntity versionEntity = repository.getProjectVersionEntity(searchEntity);
        if (Objects.isNull(versionEntity)) {
            log.error("deleteProjectVersion id is not exist");
            return CommonResult.error().setMessage("deleteProjectVersion id is not exist");
        }
        // 判断是否有操作项目的权限
        CommonResult<Object> result = checkOperateProject(versionEntity.getProjectId());
        if (Objects.nonNull(result)) {
            return result;
        }
        // 删除数据
        YwuDemandManageProjectVersionEntity delete = new YwuDemandManageProjectVersionEntity();
        delete.setId(dto.getId());
        repository.deleteProjectVersion(delete);
        return CommonResult.success(null);
    }

    /**
    * @Author GroundDemo
    * @Description 项目版本下拉查询
    * @Date 21:54 2025/3/31
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryVersionListForDropDown(YwuDemandManageProjectVersionDto dto) {
        if (StringUtils.isEmpty(dto.getProjectId())) {
            return CommonResult.success(new ArrayList<>());
        }
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        dto.setTenantId(currentContext.getYwuContextTenant().getTenantId());
        List<YwuDemandManageProjectVersionEntity> versionList = repository.queryVersionListNoPage(dto);
        return CommonResult.success(versionList);
    }

    /**
    * @Author GroundDemo
    * @Description 查询当前用户参与的项目列表
    * @Date 14:14 2025/4/5
    * @Param [dto]
    * @return com.ywu.common.result.CommonResult<java.lang.Object>
    **/
    public CommonResult<Object> queryProjectListByUser(YwuDemandManageProjectDto dto) {
        YwuContext currentContext = YwuContextHolder.getCurrentContext();
        Integer id = currentContext.getYwuContextUser().getId();
        YwuDemandManageProjectGroupEntity search = new YwuDemandManageProjectGroupEntity();
        search.setUserId(String.valueOf(id));
        List<YwuDemandManageProjectEntity> resList = repository.queryProjectListByUser(search);
        return CommonResult.success(resList);
    }
}
